﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using System.ComponentModel;



[assembly: WebResource("MVCnExt.Web.UI.Ext.Scripts.widgets.Panel.min.js", "application/x-javascript")]
namespace MVCnExt.Web.UI.Ext
{
    /// <summary>
    /// This is a control that uses requires the use of javascript
    /// and so it writes its own javascript code to an external
    /// file and registers the file as an include
    /// </summary>
    [ParseChildren(true)]
    [PersistChildren(false)]
    public abstract class ExtControl : Panel, IScriptControl
    {
        //reference to ScriptManagerBase control
        private ScriptManagerBase _manager;
        
        private List<ClientEvent> _events = new List<ClientEvent>();

        public ExtControl()
        {
           
        }

        protected internal ScriptManagerBase ScriptManager
        {
            get
            {
                return _manager;
            }
        }

        /// <summary>
        /// Register control and control dependencies
        /// </summary>
        /// <param name="e"></param>            
        protected override void OnPreRender(EventArgs e)
        {
            if (!this.DesignMode)
            {
                _manager = ScriptManagerBase.GetCurrent(Page);

                if (_manager == null)
                    throw new System.Web.HttpException("A ScriptManagerBase control must exist on this page");

                //make sure to register styles if we're using System.Web.UI.ScriptManager
                if(String.CompareOrdinal(_manager.GetType().Name, "ScriptManagerWrapper") == 0)
                    ExtScriptManager.RegisterFrameworkStyles(_manager.ClientScript);


                // registers the control with the ScriptManager so it will call GetScriptReferences()
                _manager.RegisterScriptControl(this);

                // we need to register Descriptors with the NamingContainer's 
                // Control collection (eg. "items") instead
                //if (!(this.NamingContainer is ExtJsContainer))
                {
                    // passes control reference to ScriptManager so it will call GetScriptDescriptors()
                    _manager.RegisterScriptDescriptors(this);
                }
            }
           
            base.OnPreRender(e);
        }

        
        /// <summary>
        /// Supports ClientEvent objects to allow references to client scripts to be added.
        /// </summary>
        /// <param name="obj"></param>
        protected override void AddParsedSubObject(object obj)
        {
            // check to see if object is ClientEvent
            if (obj is ClientEvent)
            {
                // add the event
                _events.Add((ClientEvent)obj);

                // client events don't have any UI, so just return
                return;
            }

            // handle all other object types
            base.AddParsedSubObject(obj);
        }

        /// <summary>
        /// Registers ClientEvent objects with the control as properties of the client-side
        /// object.
        /// </summary>
        /// <param name="descriptor"></param>
        protected virtual void RegisterClientEvents(ScriptControlDescriptorBase descriptor)
        {
            // add all client events as script properties
            foreach (ClientEvent e in ClientEvents)
            {
                descriptor.AddPropertyBase(e.name, e.action);
            }
        }

        /// <summary>
        /// Client-side event handlers
        /// </summary>
        [NotifyParentProperty(true)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        private List<ClientEvent> ClientEvents
        {
            get
            {
                return _events;
            }            
        }

        protected String GetControlID(String name)
        {
            Control control = FindControl(name);
            if (control == null)
                return name;
            return control.ClientID;
        }

        #region IScriptControl Members

        /// <summary>
        /// Register the key/value pairs which will be used to render the client-side
        /// object as script.
        /// </summary>
        /// <returns>A list of key/value pairs which comprise the client-side properties
        /// of this control</returns>
        public virtual IList<ScriptDescriptor> GetScriptDescriptors()
        {
            List<ScriptDescriptor> descriptors = new List<ScriptDescriptor>();

            return descriptors;
        }

        /// <summary>
        /// Register external script references to be added to the page
        /// </summary>
        /// <returns>A list of external scripts upon which this control (or its children)
        /// are dependent.</returns>
        public virtual List<ScriptReference> GetScriptReferences()
        {
            List<ScriptReference> references = new List<ScriptReference>();

            if (Page != null)
            {
                //make sure to register framework scripts if we're using System.Web.UI.ScriptManager
                if (String.CompareOrdinal(_manager.GetType().Name, "ScriptManagerWrapper") == 0)
                    references = ExtScriptManager.GetFrameworkScripts(ScriptManager.ClientScript);
            }

            return references;
        }

        IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
        {
            return this.GetScriptReferences();
        }

        IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
        {
            return this.GetScriptDescriptors();
        }
        #endregion

        [Browsable(false)]
        [ReadOnly(true)]
        public override String AccessKey { get; set; }

        [Browsable(false)]
        [ReadOnly(true)]
        public override System.Drawing.Color BackColor { get; set; }

        [Browsable(false)]
        [ReadOnly(true)]
        public override System.Drawing.Color BorderColor { get; set; }

        [Browsable(false)]
        [ReadOnly(true)]
        public override BorderStyle BorderStyle { get; set; }

        [Browsable(false)]
        [ReadOnly(true)]
        public override Unit BorderWidth { get; set; }

        [Browsable(false)]
        [ReadOnly(true)]
        public override String CssClass { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //public override bool Enabled { get; set; }

        [Browsable(false)]
        [ReadOnly(true)]
        public override bool EnableTheming { get; set; }

        [Browsable(false)]
        [ReadOnly(true)]
        public new string Font { get; set; }

        [Browsable(false)]
        [ReadOnly(true)]
        public override System.Drawing.Color ForeColor { get; set; }

        [Browsable(false)]
        [ReadOnly(true)]
        public override String SkinID { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //public override Unit Height { get; set; }

        [Browsable(false)]
        [ReadOnly(true)]
        public override short TabIndex { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //protected override HtmlTextWriterTag TagKey { get { return new HtmlTextWriterTag(); } }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //protected override String TagName { get { return ""; } }

        [Browsable(false)]
        [ReadOnly(true)]
        public override String ToolTip { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //public override Unit Width { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //public override String BackImageUrl { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //public override String DefaultButton { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //public override ContentDirection Direction { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //public override String GroupingText { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //public override HorizontalAlign HorizontalAlign { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //public override ScrollBars ScrollBars { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //public override bool Wrap { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //public override bool EnableViewState { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //public override bool Visible { get; set; }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //protected override void OnDataBinding(EventArgs e) { }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //protected internal new void OnInit(EventArgs e) { }

        //[Browsable(false)]
        //[ReadOnly(true)]
        //protected internal new void OnLoad(EventArgs e) { }     

        //[Browsable(false)]
        //[ReadOnly(true)]
        //protected internal new void OnUnload(EventArgs e) { }       
    }

}
